﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using BlogML.Xml;
using System.Web.Security;
using Blazing.BusinessObjects.Tagging;
using Blazing.BusinessObjects.Cms;
using System.BusinessObjects.Data;
using System.Diagnostics;

namespace Blazing.WebFacade
{
    public class BlogMLController
    {
        TaggingController tagController = new TaggingController();
        PageController pageController = new PageController();
        ThemeController themeController = new ThemeController();
        SiteController siteController = new SiteController();

        public void Import(Stream fileStream)
        {
            var blog = BlogMLSerializer.Deserialize(fileStream);

            Uri u = new Uri(blog.RootUrl);
            Site site = siteController.GetSite(u.Host);

            if (site == null)
            {
                site = new Site();
                site.Url = u.Host;
                site.Name = blog.Title;
                site.Save();

                Masterpage m = new Masterpage
                {
                    Name = "Default",
                    Path = "~/Default.master",
                    Site = site,
                    Description = "Default masterpage"
                };
                Theme t = new Theme
                {
                    Name = "Default",
                    Description = "Default theme",
                    Masterpage = m,
                    Path = "Default"
                };
                m.Themes.Add(t);
                site.Masterpages.Add(m);
                m.Save();
                t.Save();
            }

            Dictionary<string, string> blogAuthors = new Dictionary<string, string>();
            foreach (var author in blog.Authors)
            {
                string username = Membership.GetUserNameByEmail(author.Email);
                if (string.IsNullOrEmpty(username))
                {
                    //create user
                    var newAuth = CreateUser(author);
                    blogAuthors.Add(newAuth.Key, newAuth.Value);
                }
                else
                {
                    blogAuthors.Add(author.ID, username);
                }
            }

            Dictionary<string, TaxonomyTag> categories = ProcessCategories(blog.Categories);
            var blogentryTag = GetBlogEntryTaxTag(blog.Title);

            foreach (var post in blog.Posts)
            {
                ProcessPage(post, categories, blogentryTag, blogAuthors, site);
            }            
        }

        public KeyValuePair<string,string> CreateUser(BlogMLAuthor user)
        {
            var memuser = Membership.CreateUser(user.Title, user.Email, user.Email);
            Roles.AddUserToRole(memuser.UserName, "Administrator");

            return new KeyValuePair<string, string>(user.ID, memuser.UserName);
        }

        public Dictionary<string,TaxonomyTag> ProcessCategories(BlogML.Xml.BlogMLBlog.CategoryCollection categories)
        {
          IList<string> categoryList = new List<string>();

            foreach(BlogMLCategory bc in categories)
            {
                categoryList.Add(bc.Title);
            }

            var taxonomy = tagController.GetTaxonomyByName("Categories");
            if(taxonomy == null)
            {
                taxonomy = new Taxonomy
                {
                    Name = "Categories",
                    Slug = "categories",
                    TaxonomyType = TaxonomyType.Load(2)
                };
                taxonomy.Save();
            }
            //Process list into tags
            var list = tagController.ProcessTagList(taxonomy.ID, null, categoryList, true);
            Dictionary<string, TaxonomyTag> catList = new Dictionary<string, TaxonomyTag>();

            foreach (var cat in list)
            {
                catList.Add(categories.Find(c => c.Title == cat.Tag.Name).ID, cat);
            }

            return catList;
        }

        public void ProcessPage(BlogMLPost post, Dictionary<string, TaxonomyTag> categories, List<TaxonomyTag> blogentryTag,
            Dictionary<string, string> blogAuthors, Site site)
        {
            string url = post.PostUrl;
            Uri u = new Uri(url);
            string path = u.PathAndQuery;
            path = path.Replace(".aspx", "/");

            var page = pageController.GetPage(site.ID, path);
            if (page == null)
            {
                page = new Contentpage();
                page.Content = post.Content.Text;
                page.CreatedBy = blogAuthors[post.Authors[0].Ref];
                page.CreatedDate = post.DateCreated;
                page.IsActive = post.Approved;
                page.Name = post.Title;
                page.PageTitle = post.Title;
                page.Site = site;
                page.Url = path;

                var master = themeController.GetMasterpages(site.ID).First();
                page.Masterpage = master;
                page.Theme = master.Themes.First();
                page.PageType = pageController.GetPageTypes()[0];

                page.TaxonomyTags.AddAll(blogentryTag);
                foreach (BlogMLCategoryReference cat in post.Categories)
                {
                    if (categories.ContainsKey(cat.Ref))
                        page.TaxonomyTags.Add(categories[cat.Ref]);
                    else
                    {
                        Trace.WriteLine(string.Format("Warning category reference {0} not found", cat.Ref));
                        //Debugger.Break();
                    }
                }

                foreach (BlogMLComment feedback in post.Comments)
                {
                    FeedbackItem item = new FeedbackItem();
                    item.Content = feedback.Content.Text;
                    item.CreatedDate = feedback.DateCreated;
                    item.IsApproved = feedback.Approved;
                    item.Name = feedback.Title;
                    item.UserEmail = feedback.UserEMail;
                    item.UserName = feedback.UserName;
                    item.UserUrl = feedback.UserUrl;
                    page.FeedbackItems.Add(item);
                    item.Save();
                }

                //Flush collections
                page.Save(SaveMode.Flush);
            }
        }

        private List<TaxonomyTag> GetBlogEntryTaxTag(string blogName)
        {
            var retList = new List<TaxonomyTag>();
            var taxonomyPosts = tagController.GetTaxonomyByName("Posts");
            if (taxonomyPosts == null)
            {
                taxonomyPosts = new Taxonomy
                {
                    Name = "Posts",
                    Slug = "posts",
                    TaxonomyType = TaxonomyType.Load(2)
                };
                taxonomyPosts.Save();
            }

            var foundTag = taxonomyPosts.TaxonomyTags.SingleOrDefault(t => t.Slug == "content-post");
            if (foundTag == null)
            {
                Tag t = new Tag
                {
                    Name = "Blog Post",
                    Slug = "post"
                };
                t.Save();
                TaxonomyTag blogTaxTag = new TaxonomyTag
                {
                    Tag = t,
                    Taxonomy = taxonomyPosts,
                    Description = "Indicates a blog post",
                    Slug = "content-post",
                    IsSelectable = true,
                    IsVisible = true
                };
                taxonomyPosts.TaxonomyTags.Add(blogTaxTag);
                blogTaxTag.Save();
                taxonomyPosts.Save();
                foundTag = blogTaxTag;
            }
            retList.Add(foundTag);

            string thisBlogSlug = UrlHelper.FormatFriendly(blogName);
            foundTag = taxonomyPosts.TaxonomyTags.SingleOrDefault(t => t.Slug == thisBlogSlug);
            if (foundTag == null)
            {
                Tag t = new Tag
                {
                    Name = blogName,
                    Slug = thisBlogSlug
                };
                t.Save();
                TaxonomyTag blogTaxTag = new TaxonomyTag
                {
                    Tag = t,
                    Taxonomy = taxonomyPosts,
                    Description = "Indicates a blog post",
                    Slug = thisBlogSlug,
                    IsSelectable = true,
                    IsVisible = true
                };
                taxonomyPosts.TaxonomyTags.Add(blogTaxTag);
                blogTaxTag.Save();
                taxonomyPosts.Save();
                foundTag = blogTaxTag;
            }
            retList.Add(foundTag);

            return retList;
        }
    }
}
